#pragma once
#include <iostream>
#include <string>
#include <unordered_map>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <strings.h>
#include <cstring>

namespace USER
{
    using namespace std;
    class User
    {
    public:
        User(string ip, uint16_t port) : _ip(ip), _port(port)
        {
        }
        ~User()
        {
        }
        string _ip;
        uint16_t _port;
    };

    class OnlineUser
    {
    public:
        OnlineUser()
        {
        }
        void addUser(const string ip, uint16_t port)
        {
            string name = ip + "-" + to_string(port);
            Users.insert(make_pair(name, User(ip, port)));
        }
        void delUser(const string ip, uint16_t port)
        {
            string name = ip + "-" + to_string(port);
            Users.erase(name);
        }
        bool IsOnline(const string ip, uint16_t port)
        {
            string name = ip + "-" + to_string(port);
            return Users.find(name) == Users.end()  ? false:true;
        }

        void boardcastmessage(int _sockfd,string clientip,uint16_t clientport,string& message)
        {
            string str;
            for(auto user:Users)
            {
                struct sockaddr_in bcmessage;
                bzero(&bcmessage,sizeof(bcmessage));
                bcmessage.sin_family = AF_INET;
                bcmessage.sin_addr.s_addr =inet_addr(user.second._ip.c_str());
                bcmessage.sin_port = htons(user.second._port); 
                str = clientip +'-'+ to_string(clientport) + '#';
                str += message;
                sendto(_sockfd,str.c_str(),str.size(),0,(struct sockaddr*)&bcmessage,sizeof(bcmessage));
            }
        }
        ~OnlineUser()
        {
        }

    private:
        unordered_map<string, User> Users;
    };


}